home *** CD-ROM | disk | FTP | other *** search
/ MIDICraft's MIDINET CD-ROM / MIDICraft's MIDINET CD-ROM.iso / DOSUTILS / KORG / SENDSYX.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-30  |  10.2 KB  |  564 lines

  1. // sysex: (c) Günter Nagler 1996
  2. #include <stdio.h>
  3. #include <ctype.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <conio.h>
  7. #include "filei3.hpp"
  8. #include "sndcard.hpp"
  9.  
  10. static char* version = "sendsyx v1.0 by Günter Nagler (" __DATE__ ")";
  11.  
  12. Soundcard* card = 0;
  13.  
  14. char* inputname = 0;
  15. int echo = 0;
  16. long skip = 0;
  17. long count = 0x7fffffffL;
  18. int isbinary = 0;
  19. int encode = 0;
  20. int binaryencode = 0;
  21. unsigned char dumb[8];
  22. unsigned char byte[7];
  23. int bytelen = 0;
  24. long sum = 0;
  25. int reply = 1;
  26.  
  27. int escape()
  28. {
  29. static int esc = 0;
  30.  
  31.   if (esc)
  32.     return 1;
  33.   while (kbhit())
  34.     if (getch() == 27)
  35.       return esc = 1;
  36.   return 0;
  37. }
  38.  
  39. void checkreply()
  40. {
  41. #define RETRY   100
  42.  
  43.   printf("waiting for reply...");
  44.  
  45.   unsigned char buf[4], data;
  46.  
  47.   int insysex = 0;
  48.   int state = 0;
  49.  
  50.   card->startinput();
  51.   for (int i = 0; i < RETRY; i++)
  52.   {
  53.     int len = card->hear(buf, sizeof(buf));
  54.     if (len <= 0)
  55.     {
  56.        if (escape())
  57.      break;
  58.        continue;
  59.     }
  60.     if (escape())
  61.       break;
  62.     for (int j = 0; j < len; j++)
  63.     {
  64.       data = buf[j];
  65.       if (insysex)
  66.       {
  67.     printf(" %02x", data);  // should be F7
  68.     if (data & 0x80)
  69.       break;
  70.       }
  71.       else
  72.       {
  73.     if (data == 0xf0)
  74.     {
  75.       printf("\nreply: %02x", data);
  76.       insysex = 1;
  77.     }
  78.     else
  79.       ;
  80.  
  81.     if (data == 0xf8 || data == 0xfe)
  82.     {
  83.       if (state == 0)
  84.         fprintf(stderr, "*\b");
  85.       else if (state == 12)
  86.         fprintf(stderr, " \b");
  87.       state++; if (state >= 24) state = 0;
  88.     }
  89.     // ignore
  90.       }
  91.     }
  92.     if (j < len)
  93.       break;
  94.   }
  95.   card->stopinput();
  96.   if (insysex)
  97.     printf("\n");
  98.   else
  99.     printf(" no reply\n");
  100. }
  101.  
  102. void checkresponse()
  103. {
  104. #define RESPONSE_RETRY   100
  105.  
  106.   card->startinput();
  107.  
  108.   unsigned char data;
  109.  
  110.   for (long i = 0; i < RESPONSE_RETRY; i++)
  111.   if (card->hear(&data, 1))
  112.      break;
  113.   if (i == RETRY)
  114.     fprintf(stderr, "Warning: no response. Transfer might not work.\n");
  115.   card->stopinput();
  116. }
  117.  
  118. int flushbytes()
  119. {
  120.   if (bytelen == 0)
  121.     return 1;
  122.   int dumblen = code7to8(byte, bytelen, dumb);
  123.   bytelen = 0;
  124.   sum += dumblen;
  125.   return card->play(dumb, dumblen) == dumblen;
  126. }
  127.  
  128. int sendbyte(unsigned char data)
  129. {
  130.   if (encode)
  131.   {
  132.     // add to encode buffer
  133.     byte[bytelen++] = data;
  134.     if (bytelen == 7)
  135.       return flushbytes();
  136.     return 1;
  137.   }
  138.   else if (bytelen > 0) // buffer contains data to encode
  139.   {
  140.     if (!flushbytes())
  141.       return 0;
  142.   }
  143.   sum ++;
  144.   if (card->play(&data, 1) != 1)
  145.   {
  146.     fprintf(stderr, "could not send byte %s\n", data);
  147.     return 0;
  148.   }
  149.   if (echo)
  150.     printf("%02X ", data);
  151.   return 1;
  152. }
  153.  
  154. int sendbytes(unsigned char* data, int len)
  155. {
  156.   if (!data)
  157.     return 0;
  158.   while (len-- > 0)
  159.   {
  160.     if (!sendbyte(*data++))
  161.       return 0;
  162.   }
  163.   return 1;
  164. }
  165.  
  166. int sendcontrol(unsigned char ctrl, unsigned char val)
  167. {
  168. unsigned char data[3];
  169.  
  170.   data[0] = 0xb0;
  171.   data[1] = ctrl;
  172.   data[2] = val;
  173.   for (int c = 0; c < 16; c++)
  174.   {
  175.     sum += 3;
  176.     if (card->play(data, 3) != 3)
  177.     {
  178.       fprintf(stderr, "could not send control: B0 %02X %02X\n", ctrl, val);
  179.       return 0;
  180.     }
  181.     data[0]++;
  182.   }
  183.   return 1;
  184. }
  185.  
  186. int testbinary(FILE* f)
  187. {
  188. long oldpos = ftell(f);
  189. int c;
  190.  
  191.   while ((c = fgetc(f)) != EOF)
  192.   {
  193.     if (c < ' ' && !isspace(c))
  194.       break;
  195.     if (c >= 0x80)
  196.       break;
  197.   }
  198.   fseek(f, oldpos, SEEK_SET);
  199.   if (c == EOF)
  200.     return 0;
  201.   else
  202.     return 1;
  203. }
  204.  
  205. int get(FILE* inf, char* &inbuf)
  206. {
  207.   if (inbuf)
  208.   {
  209.     if (*inbuf == 0)
  210.       return EOF;
  211.     else
  212.       return *inbuf++;
  213.   }
  214.   if (inf)
  215.     return fgetc(inf);
  216.   return EOF;
  217. }
  218.  
  219. int sendsysex(char* filename);
  220.  
  221. int hexval(int c)
  222. {
  223.   if (isdigit(c))
  224.     return c - '0';
  225.   else if (isxdigit(c))
  226.     return toupper(c) - 'A' + 10;
  227.   else
  228.     return -1;
  229. }
  230.  
  231. int hexval(char* s)
  232. {
  233. int v1, v2;
  234.  
  235.   if (!s || (v1 = hexval(*s)) < 0)
  236.     return -1;
  237.   if (s[1] == 0)
  238.     return v1;
  239.   if (s[2])
  240.     return -1;
  241.   v2 = hexval(s[1]);
  242.   if (v2 < 0)
  243.     return -1;
  244.   return (v1 << 4) + v2;
  245. }
  246.  
  247. int sendtextsyx(FILE* f, char* buf)
  248. {
  249.     int c = get(f, buf);
  250.     // assume text
  251.     while (c != EOF)
  252.     {
  253.       if (escape())
  254.     break;
  255.       if (isspace(c))
  256.     ;
  257.       else if (c == '/')
  258.       {
  259.     c = get(f, buf);
  260.     if (c == '/')
  261.     {
  262.       while (c != EOF && c != '\n')
  263.         c = get(f, buf);
  264.     }
  265.     else
  266.     {
  267.       fprintf(stderr, "invalid character / ignored\n");
  268.       continue;
  269.     }
  270.       }
  271.       else
  272.       {
  273.       char ident[128];
  274.       int len = 0;
  275.     // keyword?
  276.  
  277.     while (c != EOF && !isspace(c))
  278.     {
  279.       if (len < sizeof(ident)-1)
  280.         ident[len++] = c;
  281.       c = get(f, buf);
  282.     }
  283.     ident[len] = '\0';
  284.  
  285.     int value;
  286.  
  287.     if ((value = hexval(ident)) >= 0)
  288.     {
  289.       if (!sendbyte(value))
  290.          break;
  291.       continue;
  292.     }
  293.  
  294.     if (stricmp(ident, "gmon") == 0)
  295.     {
  296.       if (!sendbytes("\xF0\x7E\x7F\x09\x01\xF7", 6))
  297.        break;
  298.     }
  299.     else if (stricmp(ident, "identify") == 0)
  300.     {
  301.       if (!sendbytes("\xf0\x7e\x00\x06\x01\xf7", 6))
  302.        break;
  303.     }
  304.     else if (stricmp(ident, "xgon") == 0)
  305.     {
  306.       if (!sendbytes("\xF0\x08\x43\x10\x4c\x00\x00\x7e\x00\xf7", 10))
  307.        break;
  308.     }
  309.     else if (stricmp(ident, "gson") == 0)
  310.     {
  311.       if (!sendbytes("\xF0\x0a\x41\x10\x42\x12\x40\x00\x7f\x00\x41\xf7", 12))
  312.        break;
  313.     }
  314.     else if (stricmp(ident, "gsoff") == 0)
  315.     {
  316.       if (!sendbytes("\xF0\x0a\x41\x10\x42\x12\x40\x00\x7f\x7f\x42\xf7", 12))
  317.        break;
  318.     }
  319.     else if (stricmp(ident, "localon") == 0)
  320.     {
  321.       if (!sendcontrol(0x7a, 127))
  322.        break;
  323.     }
  324.     else if (stricmp(ident, "localoff") == 0)
  325.     {
  326.       if (!sendcontrol(0x7a, 0))
  327.        break;
  328.     }
  329.     else if (stricmp(ident, "notesoff") == 0)
  330.     {
  331.       if (!sendcontrol(0x7b, 0))
  332.        break;
  333.     }
  334.     else if (stricmp(ident, "omnioff") == 0)
  335.     {
  336.       if (!sendcontrol(0x7c, 0))
  337.        break;
  338.     }
  339.     else if (stricmp(ident, "omnion") == 0)
  340.     {
  341.       if (!sendcontrol(0x7d, 0))
  342.        break;
  343.     }
  344.     else if (stricmp(ident, "polyoff") == 0)
  345.     {
  346.       if (!sendcontrol(0x7e, 0))
  347.        break;
  348.     }
  349.     else if (stricmp(ident, "polyon") == 0)
  350.     {
  351.       if (!sendcontrol(0x7f, 0))
  352.        break;
  353.     }
  354.     else if (stricmp(ident, "sox") == 0)
  355.     {
  356.       if (!sendbyte(0xf0))
  357.        break;
  358.     }
  359.     else if (stricmp(ident, "eox") == 0)
  360.     {
  361.       if (!sendbyte(0xf7))
  362.        break;
  363.     }
  364.     else
  365.     {
  366.       // try if it is a filename
  367.       FILE* f = fopen(ident, "rb");
  368.       if (f)
  369.       {
  370.         fclose(f);
  371.         sendsysex(ident);
  372.         continue;
  373.       }
  374.       else if (strchr(ident, '.'))
  375.         perror(ident);
  376.       else
  377.         fprintf(stderr,"unknown identifier %s ignored\n", ident);
  378.       return 0;
  379.     }
  380.     continue;
  381.       }
  382.       c = get(f, buf);
  383.     }
  384.     return 1;
  385. }
  386.  
  387. int sendsysex(char* filename)
  388. {
  389.   FILE* f = fopen(filename, "rb");
  390.   if (!f)
  391.   {
  392.     perror(filename);
  393.     return 1;
  394.   }
  395.   int looksbinary = isbinary || testbinary(f);
  396.   int c;
  397.  
  398.   if (!looksbinary)
  399.   {
  400.     return sendtextsyx(f, 0) != 0;
  401.   }
  402.   else
  403.   {
  404.     if (count <= 0)
  405.       count = 0x7fffffffL;
  406.  
  407.     if (skip < 0)
  408.       skip = 0;
  409.  
  410.     encode = binaryencode;
  411.     if (encode && echo)
  412.       printf("<encoded data> ");
  413.     fseek(f, skip, SEEK_SET);
  414.     skip = 0;
  415.     c = fgetc(f);
  416.     // assume binary
  417.     while (c != EOF && count > 0)
  418.     {
  419.       if (escape())
  420.     break;
  421.       count--;
  422.       if (!sendbyte(c))
  423.     break;
  424.       c = fgetc(f);
  425.     }
  426.     encode = 0;
  427.     count = 0;
  428.   }
  429.  
  430.   fclose(f);
  431.   return 0;
  432. }
  433.  
  434. int main(int argc, char** argv)
  435. {
  436.   argc--; argv++;
  437.  
  438.   int ret = 0;
  439.  
  440.   if (argc == 0)
  441.   {
  442.      printf("%s\n", version);
  443.      printf("usage: sysex [-noreply] [-skip #] [-count #] [-echo] [-enc] [-raw] [hex] [cmd] [file] ...\n");
  444.      printf("-noreply don't wait for a reply\n");
  445.      printf("-skip #  skip bytes of next binary file\n");
  446.      printf("-count # read count bytes of next binary file (default: read till end)\n");
  447.      printf("-echo    echo sent bytes in hexadecimal format\n");
  448.      printf("-enc     dump encode bytes read from binary files\n");
  449.      printf("-raw     do not encode bytes read from binary files\n");
  450.      printf("hex      send byte (e.g. f0 42 a f7)\n");
  451.      printf("cmd      send command (e.g. gmon notesoff ...)\n");
  452.      printf("file     end content of binary or hex file\n");
  453.      printf("All parameters can be used more than once. Text files can contain hex, cmd, file\n");
  454.      printf("-skip,-count,-enc only affect next binary file\n");
  455.      return 1;
  456.   }
  457.  
  458.   card = detect_soundcard();
  459.   if (!card)
  460.   {
  461.     fprintf(stderr, "Could not detect soundcard\n");
  462.     return 1;
  463.   }
  464.  
  465.   checkresponse();
  466.  
  467.   while (argc > 0)
  468.   {
  469.     if (escape())
  470.       break;
  471.     if (**argv == '-')
  472.     {
  473.       if (strnicmp(*argv, "-version", 2) == 0)
  474.       {
  475.     fprintf(stderr, "%s\n", version);
  476.     *argv = 0;
  477.     argc--; argv++;
  478.       }
  479.       if (strnicmp(*argv, "-binary", 2) == 0)
  480.       {
  481.     isbinary = 1;
  482.     argc--; argv++;
  483.     continue;
  484.       }
  485.       if (strnicmp(*argv, "-noreply", 2) == 0)
  486.       {
  487.     reply = 0;
  488.     argc--; argv++;
  489.     continue;
  490.       }
  491.       if (strnicmp(*argv, "-encode", 3) == 0)
  492.       {
  493.     binaryencode = 1;
  494.     argc--; argv++;
  495.     continue;
  496.       }
  497.       if (strnicmp(*argv, "-raw", 2) == 0)
  498.       {
  499.     encode = 0;
  500.     argc--; argv++;
  501.     continue;
  502.       }
  503.       if (strnicmp(*argv, "-echo", 2) == 0)
  504.       {
  505.     echo = 1;
  506.     argc--; argv++;
  507.     continue;
  508.       }
  509.       if (strnicmp(*argv, "-skip", 2) == 0)
  510.       {
  511.     argc--; argv++;
  512.     if (argc == 0 || !isxdigit(**argv))
  513.       fprintf(stderr, "option -skip needs a value\n");
  514.     else
  515.     {
  516.     char* endptr = 0;
  517.  
  518.       skip = strtoul(*argv, &endptr, 0);
  519.       if (endptr && *endptr)
  520.         fprintf(stderr, "%s is not a legal value\n", *argv);
  521.       argc--; argv++;
  522.     }
  523.     continue;
  524.       }
  525.       if (strnicmp(*argv, "-count", 2) == 0)
  526.       {
  527.     argc--; argv++;
  528.     if (argc == 0 || !isxdigit(**argv))
  529.       fprintf(stderr, "option -count needs a value\n");
  530.     else
  531.     {
  532.     char* endptr = 0;
  533.  
  534.       count = strtoul(*argv, &endptr, 0);
  535.       if (endptr && *endptr)
  536.         fprintf(stderr, "%s is not a legal value\n", *argv);
  537.       argc--; argv++;
  538.     }
  539.     continue;
  540.       }
  541.       fprintf(stderr, "invalid option %s\n", *argv);
  542.       argc--; argv++; continue;
  543.     }
  544.     else
  545.     {
  546.     char* arg = *argv++; argc--;
  547.     int arglen = strlen(arg);
  548.  
  549.       if (arglen == 0)
  550.     continue;
  551.       sendtextsyx(0, arg);
  552.     }
  553.   }
  554.  
  555.   if (sum > 0 && reply)
  556.   {
  557.     printf("\n%ld bytes sent, ", sum);
  558.     checkreply();
  559.   }
  560.  
  561.   delete card;
  562.   return ret;
  563. }
  564.